package co.edu.uniandes.distribuidos.fss.adv;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Enumeration;

import net.jxta.document.Advertisement;
import net.jxta.document.Document;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.id.ID;

public class FileAdvertisement extends Advertisement implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 2940708381671371664L;

	private String contentType;
	
	private String keywords;
	
	private long size=-1;
	
	private String name;
	
	private FileID fileID;
	
	private String address;
	private String url;
	private String pipeID;
	
	public static final String CONTENT_TYPE_TAG_NAME="contentType";
	
	public static final String SIZE_TAG_NAME="size";
	
	public static final String NAME_TAG_NAME="name";
	
	public static final String ID_TAG_NAME="id";
	
	public static final String KEYWORDS_TAG_NAME = "keywords";
	
	private final static String[] fields = {ID_TAG_NAME, NAME_TAG_NAME, SIZE_TAG_NAME,KEYWORDS_TAG_NAME};

	private static final String ADDRESS_TAG_NAME = "address";
	private static final String URL_TAG_NAME = "url";
	
	public static final String ID_PIPE="idPipe";
	
	

	@SuppressWarnings("unchecked")
	public FileAdvertisement(Element element) {
		 TextElement doc = (TextElement) element;
	        if (!getAdvertisementType().equals(doc.getName())) {
	            throw new IllegalArgumentException("Could not construct : " +
	                    getClass().getName() + "from doc containing a " + 
	                    doc.getName());
	        }
	        initialize(doc);
	}

	@SuppressWarnings("unchecked")
	private void initialize(TextElement doc) {
        if (!doc.getName().equals(getAdvertisementType())) {
            throw new IllegalArgumentException("Could not construct : "
                    + getClass().getName() + "from doc containing a " +
                    doc.getName());
        }
        Enumeration elements = doc.getChildren();
        while (elements.hasMoreElements()) {
            TextElement elem = (TextElement) elements.nextElement();
            if (!handleElement(elem)) {
            	System.out.println("Imposible translate element" + elem);
            }
        }
		
	}

	@SuppressWarnings("unchecked")
	private boolean handleElement(TextElement elem) {
		if(ID_TAG_NAME.equals(elem.getName())){
			setFileID(new FileID(elem.getTextValue()));
			return true;
		}
		if(CONTENT_TYPE_TAG_NAME.equals(elem.getName())){
			setContentType(elem.getTextValue());
			return true;
		}
		if(KEYWORDS_TAG_NAME.equals(elem.getName())){
			setKeywords(elem.getTextValue());
			return true;
		}
		if(SIZE_TAG_NAME.equals(elem.getName())){
			setSize(Long.valueOf(elem.getValue()));
			return true;
		}
		if(ADDRESS_TAG_NAME.equals(elem.getName())){
			setAddress(elem.getValue());
			return true;
		}if(NAME_TAG_NAME.equals(elem.getName())){
			setName(elem.getValue());
		}
		if(URL_TAG_NAME.equals(elem.getName())){
			setUrl(elem.getValue());
		}
		if (ID_PIPE.equals(elem.getName())){
			setPipeID(elem.getValue());
		}
		return false;
	}

	public FileAdvertisement() {
		fileID = new FileID();
	}

	public String getContentType() {
		return contentType;
	}

	public void setContentType(String contentType) {
		this.contentType = contentType;
	}

	public String getKeywords() {
		return keywords;
	}

	public void setKeywords(String keywords) {
		this.keywords = keywords;
	}

	public long getSize() {
		return size;
	}

	public void setSize(long size) {
		this.size = size;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	 /**
     * Creates a new ContentAdvertisement from the specified InputStream.
     * @param is the InputStream containing the advertisement
     * @exception IllegalArgumentException if the advertisement was invalid
     * @exception IOException if there was an I/O error
     */
    public FileAdvertisement(InputStream is) throws IOException {
        StructuredTextDocument doc = (StructuredTextDocument)
                                     StructuredDocumentFactory.newStructuredDocument(
                                         new MimeMediaType("text", "xml"), is);
        appendElements(doc,doc);
    }
	@SuppressWarnings("unchecked")
	@Override
	public Document getDocument(MimeMediaType mtype) {
		StructuredDocument doc = (StructuredDocument)
			StructuredDocumentFactory.newStructuredDocument(
					mtype, getAdvertisementType());
		appendElements(doc, doc);
		return doc;
	}
	
	@SuppressWarnings({"unchecked" })
	private void appendElements(StructuredDocument doc, Element e) {
		 e.appendChild(doc.createElement(ID_TAG_NAME,this.fileID.toString()));
		 e.appendChild(doc.createElement(NAME_TAG_NAME,this.name));
		 e.appendChild(doc.createElement(SIZE_TAG_NAME, String.valueOf(this.size)));
		 e.appendChild(doc.createElement(CONTENT_TYPE_TAG_NAME,this.contentType));
		 e.appendChild(doc.createElement(ADDRESS_TAG_NAME,this.address));
		 e.appendChild(doc.createElement(KEYWORDS_TAG_NAME,this.keywords));
		 e.appendChild(doc.createElement(URL_TAG_NAME,this.url));
		 e.appendChild(doc.createElement(ID_PIPE,this.pipeID));
	 }

	@Override
	public ID getID() {
		return null;
	}
	

	@Override
	public String[] getIndexFields() {
		return fields;
	}
	
	 /**
     * Returns the advertisement type
     */
    public static String getAdvertisementType() {
    	return "jxta:FileAdvertisement";
    }

	public FileID getFileID() {
		return fileID;
	}

	public void setFileID(FileID fileID) {
		this.fileID = fileID;
	}

	public void setAddress(String endpointAddress) {
		this.address=endpointAddress;
	}

	public String getAddress() {
		return address;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getPipeID() {
		return pipeID;
	}

	public void setPipeID(String pipeID) {
		this.pipeID = pipeID;
	}
	public FileAdvertisement clonar(){
		FileAdvertisement fileAdvertisement = new FileAdvertisement();
		fileAdvertisement.setFileID(fileID.clonar());
		fileAdvertisement.setContentType(contentType);
		fileAdvertisement.setKeywords(keywords);
		fileAdvertisement.setSize(size);
		fileAdvertisement.setAddress(address);
		fileAdvertisement.setName(name);
		fileAdvertisement.setUrl(url);
		fileAdvertisement.setPipeID(pipeID);
		return fileAdvertisement;
	}

}
